package com.offics.loan.application.service;

import com.offics.loan.application.dto.loan.*;
import com.offics.loan.domain.entity.Loan;
import com.offics.loan.domain.entity.LoanProduct;
import com.offics.loan.domain.repository.LoanProductRepository;
import com.offics.loan.domain.repository.LoanRepository;
import com.offics.loan.domain.service.LoanDomainService;
import com.offics.loan.infrastructure.exception.BusinessException;
import com.offics.loan.infrastructure.common.ResultCode;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 贷款应用服务
 */
@Service
@RequiredArgsConstructor
public class LoanApplicationService {

    private final LoanRepository loanRepository;
    private final LoanProductRepository loanProductRepository;
    private final LoanDomainService loanDomainService;

    /**
     * 申请贷款
     *
     * @param request 贷款申请请求
     * @return 贷款申请响应
     */
    public LoanApplyResponse applyLoan(LoanApplyRequest request) {
        Loan loan = loanDomainService.applyLoan(
                request.getUserId(),
                request.getProductId(),
                request.getAmount(),
                request.getPeriod(),
                request.getPurpose(),
                request.getBankCardId()
        );

        LoanApplyResponse response = new LoanApplyResponse();
        BeanUtils.copyProperties(loan, response);
        response.setStatusText(getStatusText(loan.getStatus()));
        return response;
    }

    /**
     * 取消贷款申请
     *
     * @param id 贷款ID
     * @return 是否成功
     */
    public boolean cancelLoan(Long id) {
        return loanDomainService.cancelLoan(id);
    }

    /**
     * 获取贷款列表
     *
     * @param userId 用户ID
     * @return 贷款列表
     */
    public List<LoanDetailResponse> getLoanList(Long userId) {
        List<Loan> loans = loanRepository.findByUserId(userId);
        return loans.stream().map(this::convertToLoanDetailResponse).collect(Collectors.toList());
    }

    /**
     * 获取贷款详情
     *
     * @param id 贷款ID
     * @return 贷款详情
     */
    public LoanDetailResponse getLoanDetail(Long id) {
        Loan loan = loanRepository.findById(id)
                .orElseThrow(() -> new BusinessException(ResultCode.LOAN_NOT_FOUND));
        return convertToLoanDetailResponse(loan);
    }

    /**
     * 获取贷款产品列表
     *
     * @return 贷款产品列表
     */
    public List<LoanProductResponse> getLoanProductList() {
        List<LoanProduct> products = loanProductRepository.findAllEnabled();
        return products.stream().map(this::convertToLoanProductResponse).collect(Collectors.toList());
    }

    /**
     * 获取贷款产品详情
     *
     * @param id 产品ID
     * @return 贷款产品详情
     */
    public LoanProductResponse getLoanProductDetail(Long id) {
        LoanProduct product = loanProductRepository.findById(id)
                .orElseThrow(() -> new BusinessException(ResultCode.LOAN_PRODUCT_NOT_FOUND));
        return convertToLoanProductResponse(product);
    }

    /**
     * 计算贷款
     *
     * @param request 贷款计算请求
     * @return 贷款计算响应
     */
    public LoanCalculateResponse calculateLoan(LoanCalculateRequest request) {
        LoanDomainService.LoanCalculationResult result = loanDomainService.calculateLoan(
                request.getAmount(),
                request.getPeriod(),
                request.getInterestRate()
        );

        LoanCalculateResponse response = new LoanCalculateResponse();
        response.setAmount(result.getAmount());
        response.setPeriod(result.getPeriod());
        response.setInterestRate(result.getInterestRate());
        response.setMonthlyPayment(result.getMonthlyPayment());
        response.setTotalPayment(result.getTotalPayment());
        response.setTotalInterest(result.getTotalInterest());

        List<LoanCalculateResponse.RepaymentPlanDetail> planDetails = new ArrayList<>();
        for (LoanDomainService.RepaymentPlanDetail detail : result.getRepaymentPlan()) {
            LoanCalculateResponse.RepaymentPlanDetail planDetail = new LoanCalculateResponse.RepaymentPlanDetail();
            BeanUtils.copyProperties(detail, planDetail);
            planDetails.add(planDetail);
        }
        response.setRepaymentPlan(planDetails);

        return response;
    }

    /**
     * 转换为贷款详情响应
     *
     * @param loan 贷款
     * @return 贷款详情响应
     */
    private LoanDetailResponse convertToLoanDetailResponse(Loan loan) {
        LoanDetailResponse response = new LoanDetailResponse();
        BeanUtils.copyProperties(loan, response);
        response.setStatusText(getStatusText(loan.getStatus()));
        return response;
    }

    /**
     * 转换为贷款产品响应
     *
     * @param product 贷款产品
     * @return 贷款产品响应
     */
    private LoanProductResponse convertToLoanProductResponse(LoanProduct product) {
        LoanProductResponse response = new LoanProductResponse();
        BeanUtils.copyProperties(product, response);
        return response;
    }

    /**
     * 获取状态文本
     *
     * @param status 状态
     * @return 状态文本
     */
    private String getStatusText(Integer status) {
        if (status == null) {
            return "";
        }
        switch (status) {
            case 0:
                return "申请中";
            case 1:
                return "审核中";
            case 2:
                return "已拒绝";
            case 3:
                return "已通过";
            case 4:
                return "已放款";
            case 5:
                return "还款中";
            case 6:
                return "已结清";
            case 7:
                return "已逾期";
            default:
                return "未知";
        }
    }
}